package xyz.zyt123.hikvideo.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * JWT工具类
 */
public class JwtUtil {

  //有效期为
  public static final Long JWT_TTL = 60 * 60 * 1000L;// 60 * 60 *1000  60 分钟
  //设置秘钥明文
  /**
   * 加密算法
   */
  private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS256;
  /**
   * 私钥 / 生成签名的时候使用的秘钥secret，一般可以从本地配置文件中读取，切记这个秘钥不能外露，只在服务端使用，在任何场景都不应该流露出去。 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。 应该大于等于 256位(长度32及以上的字符串)，并且是随机的字符串
   */
  private final static String SECRET = "secretKeycereshuzhitingnizhenbangcereshuzhitingnizhenbang";
  /**
   * 秘钥实例
   */
  public static final SecretKey KEY = Keys.hmacShaKeyFor(SECRET.getBytes());

  public static String getUUID() {
    return UUID.randomUUID().toString().replaceAll("-", "");
  }

  /**
   * 生成jtw
   *
   * @param subject
   *     token中要存放的数据（json格式）
   */
  public static String createJWT(String subject) {
    JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间
    return builder.compact();
  }

  /**
   * 生成jtw
   *
   * @param subject
   *     token中要存放的数据（json格式）
   * @param ttlMillis
   *     token超时时间
   */
  public static String createJWT(String subject, Long ttlMillis) {
    JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
    return builder.compact();
  }

  private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
    long nowMillis = System.currentTimeMillis();
    if (ttlMillis == null) {
      ttlMillis = JwtUtil.JWT_TTL;
    }
    long expMillis = nowMillis + ttlMillis;
    Date expDate = new Date(expMillis);
    return Jwts.builder()
        // 设置头部信息header
        .header()
        .add("typ", "JWT")
        .add("alg", "HS256")
        .and()
        // 设置自定义负载信息payload
        // 令牌ID
        .id(uuid)
        // 过期日期
        .expiration(expDate)
        // 签发时间
        .issuedAt(new Date())
        // 主题
        .subject(subject)
        // 签名
        .signWith(KEY, ALGORITHM);
  }

  /**
   * 解析
   */
  public static Claims parseJWT(String jwt) {
    return Jwts.parser()
        .verifyWith(KEY)
        .build()
        .parseSignedClaims(jwt)
        .getPayload();
  }
}

